#include "xmppim/stanzatask.h"
#include "xmppim/xmppclient.h"
#include "utils/uniqueid.h"
#include "xmppcore/connectionconfig.h"

namespace yoohoo_xmppim {

StanzaTask::StanzaTask(bool autoDelete, JabberId* to) : _autoDelete(autoDelete) {
	_to = 0;
	setTo(to);
}

StanzaTask::~StanzaTask() {
	delete _to;
}

void StanzaTask::setAutoDelete(bool autoDelete) {
	_autoDelete = autoDelete;
}

bool StanzaTask::autoDelete() const {
	return _autoDelete;
}

bool StanzaTask::matches(XmppClient* xmppClient, Stanza* stanza) {
	Iq* iq = dynamic_cast<Iq*>(stanza);
	if (iq != 0) {
		return taskId() == stanza->id();
	}

	return false;
}

bool StanzaTask::matches(XmppClient* xmppClient, StanzaError* error) {
	return taskId() == error->id();
}

bool StanzaTask::processError(StanzaError* error, bool& errorHandled) {
	errorHandled = false;
	return true;
}

void StanzaTask::setTo(const JabberId* to) {
	if (_to != 0) {
		delete _to;
	}

	if (to == 0) {
		_to = 0;
		return;
	}

	_to = new JabberId(*to);
}

const JabberId* StanzaTask::to() const {
	return _to;
}

void StanzaTask::setTaskId(QString taskId) {
	_taskId = taskId;
}

QString StanzaTask::taskId() {
	if (_taskId == "") {
		_taskId = yoohoo_utils::UniqueId::instance()->get();
	}

	return _taskId;
}

AbstractStanzaTask::AbstractStanzaTask(bool autoDelete, JabberId* to) : StanzaTask(autoDelete, to) {
}

bool AbstractStanzaTask::process(XmppClient* xmppClient, Stanza* stanza) {
	if (stanza == 0) {
		begin(xmppClient);
		return false;
	} else {
		return processResponse(xmppClient, stanza);
	}
}

SequentialStanzaTask::SequentialStanzaTask(bool autoDelete) : StanzaTask(autoDelete) {
}

SequentialStanzaTask::~SequentialStanzaTask() {
	for (int i = 0; i < _stanzaTasks.size(); i++) {
		StanzaTask* task = _stanzaTasks.at(i);
		if (task->autoDelete())
			delete task;
	}

	_stanzaTasks.clear();
}

bool SequentialStanzaTask::process(XmppClient* xmppClient, Stanza* stanza) {
	if (_stanzaTasks.size() == 0)
		return true;

	StanzaTask* task = _stanzaTasks.at(0);
	if (!task->process(xmppClient, stanza))
		return false;

	_stanzaTasks.removeAt(0);
	delete task;

	return process(xmppClient, 0);
}

bool SequentialStanzaTask::processError(StanzaError* error, bool& errorHandled) {
	if (_stanzaTasks.size() == 0) {
		return false;
	} else {
		StanzaTask* task = _stanzaTasks.at(0);
		return task->processError(error, errorHandled);
	}
}

SequentialStanzaTask* SequentialStanzaTask::appendTask(StanzaTask* task) {
	task->setTaskId(taskId());
	_stanzaTasks.append(task);

	return this;
}

}
